<template>
  <div>
    <!-- card背景 -->
    <el-card class="box-card">
      <!-- 功能按钮 -->
      <el-row :gutter="10">
        <el-col :span="2.5">
          <el-button type="primary" @click="invoke()" size="medium" class="edit"  icon="el-icon-check">
            发送请求
          </el-button>
          <el-button type="primary" @click="save()" size="medium" class="edit1" icon="el-icon-plus">
            接口调用并保存
          </el-button>
        </el-col>
      </el-row>

      <!-- 接口请求表单区域 -->
      <el-form
        :model="invokeHttpForm"
        :rules="rules"
        ref="invokeHttpRef"
        size="small"
        label-position="right"
      >
        <el-row :gutter="25">
          <!-- 域名 -->
          <el-col :span="7">
            <el-form-item label="接口名称：" prop="interfaceName" label-width="100px">
              <el-input v-model="invokeHttpForm.interfaceName"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="10">
            <el-form-item label="请求类型：" prop="method" label-width="100px">
              <el-select
                v-model="invokeHttpForm.type"
                placeholder="请选择"
                @change="resetInput()"
              >
                <el-option
                  v-for="item in typesOptions"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value"
                >
                </el-option>
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="25">
          <!-- 域名 -->
          <el-col :span="7">
            <el-form-item label="域名：" prop="host" label-width="100px">
              <el-input v-model="invokeHttpForm.host"></el-input>
            </el-form-item>
          </el-col>
          <!-- 接口地址 -->
          <el-col :span="10">
            <el-form-item label="接口地址：" prop="apiUrl" label-width="100px">
              <el-input v-model="invokeHttpForm.apiUrl"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="25">
          <!-- 超时时间下拉选择 -->
          <el-col :span="5">
            <el-form-item
              label="超时时间(s):"
              prop="timeOut"
              label-width="100px"
            >
              <el-select v-model="invokeHttpForm.timeOut" placeholder="请选择">
                <el-option
                  v-for="item in timeOutOptions"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value"
                >
                </el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <!-- 请求方法下拉选择-->
          <el-col :span="5">
            <el-form-item label="请求方法：" prop="methods" label-width="100px">
              <el-select
                v-model="invokeHttpForm.methods"
                placeholder="请选择"
                @change="resetInput()"
              >
                <el-option
                  v-for="item in methodsOptions"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value"
                >
                </el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <!-- 添加信息头开关 -->
          <el-col :span="2.5">
            <el-form-item
              label="信息头："
              prop="header"
              label-width="100px"
            >
              <el-switch
                v-model="isHeader"
                @change="activeChange('header')"
              ></el-switch>
            </el-form-item>
          </el-col>
          <!-- 添加请求参数开关 -->
          <el-col :span="2">
            <el-form-item
              label="请求参数："
              prop="param"
              label-width="110px"
            >
              <el-switch
                v-model="isParams"
                @change="activeChange('param')"
              ></el-switch>
            </el-form-item>
          </el-col>
          <!-- 添加请求体开关 -->
          <el-col :span="2">
            <el-form-item
              label="请求体："
              prop="body"
              label-width="140px">
              <el-switch
                v-model="isBody"
                @change="activeChange('body')"
              ></el-switch>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>

      <!-- 信息头/入参表单 -->
      <el-form :model="reqForm" ref="reqRef" size="small">
        <el-tabs v-if="isHeader || isParams || isBody" v-model="activeName">
          <!-- 消息头表单 -->
          <el-tab-pane v-if="isHeader" label="信息头" name="header">
            <el-row :gutter="22" class="title">
              <el-col :span="9">
                <span>Key:</span>
              </el-col>
              <el-col :span="9">
                <span>Value:</span>
              </el-col>
            </el-row>
            <el-form-item
              v-for="(header, index) in reqForm.headers"
              :key="index"
              :prop="'headers.' + index + '.value'"
            >
              <el-row :gutter="22">
                <el-col :span="9">
                  <el-input v-model="header.key"></el-input>
                </el-col>
                <el-col :span="9">
                  <el-input v-model="header.value"></el-input>
                </el-col>
                <el-col :span="1.5">
                  <el-button
                    type="success"
                    icon="el-icon-plus"
                    size="mini"
                    @click="add('header')"
                  ></el-button>
                </el-col>
                <el-col :span="1.5">
                  <el-button
                    v-if="index > 0"
                    type="danger"
                    icon="el-icon-delete"
                    size="mini"
                    @click.prevent="removeDomain(header, 'header')"
                  ></el-button>
                </el-col>
              </el-row>
            </el-form-item>
          </el-tab-pane>
          <!-- 请求参数表单 -->
          <el-tab-pane v-if="isParams" label="请求参数" name="param">
            <el-row :gutter="22" class="title">
              <el-col :span="9">
                <span>Key:</span>
              </el-col>
              <el-col :span="9">
                <span>Value:</span>
              </el-col>
            </el-row>
            <el-form-item
              v-for="(param, index) in reqForm.params"
              :key="index"
              :prop="'params.' + index + '.value'"
            >
              <el-row :gutter="22">
                <el-col :span="9">
                  <el-input v-model="param.key"></el-input>
                </el-col>
                <el-col :span="9">
                  <el-input v-model="param.value"></el-input>
                </el-col>
                <el-col :span="1.5">
                  <el-button
                    type="success"
                    icon="el-icon-plus"
                    size="mini"
                    @click="add('param')"
                  ></el-button>
                </el-col>
                <el-col :span="1.5">
                  <el-button
                    v-if="index > 0"
                    type="danger"
                    icon="el-icon-delete"
                    size="mini"
                    @click.prevent="removeDomain(param, 'param')"
                  ></el-button>
                </el-col>
              </el-row>
            </el-form-item>
          </el-tab-pane>
          <el-tab-pane v-if="isBody" label="请求体" name="body">
            <div style="width: 70%;margin-left: 30px;margin-top: 30px;">
              <b-code-editor v-model="invokeHttpForm.body" :auto-format="true" :smart-indent="true"  :indent-unit="4" :line-wrap="false" ref="editor"></b-code-editor>
              <br>
            </div>
          </el-tab-pane>
        </el-tabs>
      </el-form>
      <!-- 响应信息-->
      <el-tabs v-model="activeNameRes" type="border-card">
        <!-- 响应结果 -->
        <el-tab-pane label="响应结果" name="responseResult">
          <el-card class="box-card" style="margin-top:2px">
            <vue-json-pretty
              :path="'res'"
              :data="response.body"
              :deep="2"
              :showLength="true"
            >
            </vue-json-pretty>
          </el-card>
        </el-tab-pane>
        <!-- 响应头 -->
        <el-tab-pane label="响应头" name="responseHeader">
          <el-card class="box-card" style="margin-top:2px">
            <vue-json-pretty
              :path="'res'"
              :data="response.headers"
              :deep="2"
              :showLength="true"
            >
            </vue-json-pretty>
          </el-card>
        </el-tab-pane>
      </el-tabs>
    </el-card>
  </div>
</template>

<script>
import {invoke, save} from "../../src/api/testutil/testhttp";
import 'vue-json-pretty/lib/styles.css';
const jsonData =`{
  }`
export default {
  data() {
    return {
      jsonStr:jsonData,
      invokeHttpRules: {},
      loading: [],
      // 响应对象
      response: {
        headers: {},
        body: {},
        statutCode: ""
      },
      rules: {
        interfaceName: [
          { required: true, message: "接口名不能为空", trigger: "blur" }
        ],
        host: [
          { required: true, message: "host不能为空", trigger: "blur" }
        ],
        apiUrl: [
          { required: true, message: "接口地址不能为空", trigger: "blur" }
        ],
        timeOut: [
          { required: true, message: "超时时间能为空", trigger: "blur" }
        ],
        methods: [
          { required: true, message: "请求方法不能为空", trigger: "blur" }
        ]
      },
      // 接口请求时提交的表单对象
      invokeHttpForm: {
        interfaceName:"",
        host: "localhost:8082",
        apiUrl: "/test/delete",
        timeOut: "3000",
        methods: "get",
        type: "http",
        headers: "",
        params: "",
        body: "{}",
        sbody:"{}"
      },
      // 下拉列表选项
      timeOutOptions: [
        {
          value: "1000",
          label: "1秒"
        },
        {
          value: "2000",
          label: "2秒"
        },
        {
          value: "3000",
          label: "3秒"
        },
        {
          value: "4000",
          label: "4秒"
        },
        {
          value: "5000",
          label: "5秒"
        }
      ],
      methodsOptions: [
        {
          value: "get",
          label: "GET"
        },
        {
          value: "post",
          label: "POST"
        },
        {
          value: "put",
          label: "PUT"
        },
        {
          value: "delete",
          label: "DELETE"
        }
      ],
      typesOptions: [
        {
          value: "http",
          label: "HTTP"
        },
        {
          value: "https",
          label: "HTTPS"
        }
      ],
      // 判断入参和头部开关是否开启
      isHeader: false,
      isParams: false,
      isBody: false,
      // 默认tab激活状态的标签
      activeName: "",
      activeNameRes: "responseResult",
      // 请求表单对应的请求对象数组
      reqForm: {
        headers: [{ key: "", value: "" }],
        params: [{ key: "", value: "" }],
        body: ""
      }
    };
  },
  methods: {
    // 调用测试接口
    invoke() {
      if (this.invokeHttpForm.methods===""
        || this.invokeHttpForm.interfaceName===""
        || this.invokeHttpForm.host===""
        || this.invokeHttpForm.apiUrl==="" ){
        window.alert("请填写全部信息.")
      }
      else {
        console.log("调用接口");
        // 如果前端有输入，存入对象数组，则将对象数组存入一个对象并转为string
        if (this.reqForm.headers[0].key != "") {
          let headersObj = {};
          for (let i = 0; i < this.reqForm.headers.length; i++) {
            let key = this.reqForm.headers[i].key;
            let val = this.reqForm.headers[i].value;
            headersObj[key] = val;
          }
          this.invokeHttpForm.headers = JSON.stringify(headersObj);
        }
        // 如果前端有输入，存入对象数组，则将对象数组存入一个对象并转为string
        console.log("表单数据显示：", JSON.stringify(this.reqForm.params));
        console.log("json：", this.reqForm.body);
        if (this.reqForm.params[0].key != "") {
          let paramsObj = {};
          for (let i = 0; i < this.reqForm.params.length; i++) {
            var key = this.reqForm.params[i].key;
            var val = this.reqForm.params[i].value;
            paramsObj[key] = val;
            console.log("遍历表单数据key：", this.reqForm.params[i].key);
          }
          console.log("表单对象数组转对象后显示：：", JSON.stringify(paramsObj));
          if (this.invokeHttpForm.methods.includes("post")) {
            this.invokeHttpForm.params = JSON.stringify(paramsObj);
            this.invokeHttpForm.body = this.reqForm.body;
          } else if (this.invokeHttpForm.methods.includes("get")) {
            this.invokeHttpForm.params = JSON.stringify(paramsObj);
          }
          console.log("对象转请求字符串后显示：", this.invokeHttpForm.params);
        }
          try {
                JSON.parse(this.invokeHttpForm.body);
                this.openLoading();
              try {
                invoke(this.invokeHttpForm).then(res => {
                  this.loading.close();
                  this.response.headers = res.data.headers;
                  console.log("测试接口headers响应信息：", this.response.headers);
                  this.response.body = res.data.body;
                  console.log("测试接口body响应信息：", this.response.body);
                  this.response.statutCode = res.data.statusCode;
                  console.log("测试接口statusCode响应信息：", this.response.statusCode);

                  console.log("对象转请求字符串后显示json：", this.invokeHttpForm.body);
                });
              } catch (e) {
                this.loading.close();
                return false;
              }
          } catch (e) {
            console.log(e);
            window.alert("Json格式错误，访问被拒绝")
            return false;
          }
      }
    },
    openLoading() {
      this.loading = this.$loading({
        lock: true,
        text: "发送请求中",
        // spinner: "el-icon-loading",
        background: "rgba(0, 0, 0, 0.7)"
      });
    },
    isJSON(str) {
      if (typeof str == 'string') {
        try {
          JSON.parse(str);
          return true;
        } catch (e) {
          console.log(e);
          return false;
        }
      }
      console.log('It is not a string!')
    },
    save(){
      console.log("调用接口并保存");
      if (this.invokeHttpForm.methods===""
        || this.invokeHttpForm.interfaceName===""
        || this.invokeHttpForm.host===""
        || this.invokeHttpForm.apiUrl==="" ){
        window.alert("请填写全部信息.")
      }
      else {
        // 如果前端有输入，存入对象数组，则将对象数组存入一个对象并转为string
        if (this.reqForm.headers[0].key != "") {
          let headersObj = {};
          for (let i = 0; i < this.reqForm.headers.length; i++) {
            let key = this.reqForm.headers[i].key;
            let val = this.reqForm.headers[i].value;
            headersObj[key] = val;
          }
          this.invokeHttpForm.headers = JSON.stringify(headersObj);
        }
        // 如果前端有输入，存入对象数组，则将对象数组存入一个对象并转为string
        console.log("表单数据显示：", JSON.stringify(this.reqForm.params));
        console.log("json：", this.reqForm.body);
        if (this.reqForm.params[0].key != "") {
          let paramsObj = {};
          for (let i = 0; i < this.reqForm.params.length; i++) {
            var key = this.reqForm.params[i].key;
            var val = this.reqForm.params[i].value;
            paramsObj[key] = val;
            console.log("遍历表单数据key：", this.reqForm.params[i].key);
          }
          console.log("表单对象数组转对象后显示：：", JSON.stringify(paramsObj));
          if (this.invokeHttpForm.methods.includes("post")) {
            this.invokeHttpForm.params = JSON.stringify(paramsObj);
            this.invokeHttpForm.body = this.reqForm.body;
          } else if (this.invokeHttpForm.methods.includes("get")) {
            this.invokeHttpForm.params = JSON.stringify(paramsObj);
          }
          console.log("对象转请求字符串后显示：", this.invokeHttpForm.params);
        }
        try {
          JSON.parse(this.invokeHttpForm.body);
          this.openLoading();
          try {
              save(this.invokeHttpForm).then(res => {
              this.loading.close();
              this.response.headers = res.data.headers;
              console.log("测试接口headers响应信息：", this.response.headers);
              this.response.body = res.data.body;
              console.log("测试接口body响应信息：", this.response.body);
              this.response.statutCode = res.data.statusCode;
              console.log("测试接口statusCode响应信息：", this.response.statusCode);

              console.log("对象转请求字符串后显示json：", this.invokeHttpForm.body);
            });
          } catch (e) {
            this.loading.close();
            return false;
          }
        } catch (e) {
          console.log(e);
          window.alert("Json格式错误，访问被拒绝")
          return false;
        }
      }
    },
    activeChange(activeName) {
      if (activeName.includes("header") && this.isHeader) {
        console.log("header1");
        this.activeName = "header";
      } else if (activeName.includes("header")) {
        console.log("param2");
        this.activeName = "param";
      }
      if (activeName.includes("param") && this.isParams) {
        console.log("param1");
        this.activeName = "param";
      } else if (activeName.includes("param")) {
        console.log("header2");
        this.activeName = "header";
      }
      if (activeName.includes("body") && this.isBody) {
        console.log("body1");
        this.activeName = "body";
      } else if (activeName.includes("body")) {
        console.log("body2");
        this.activeName = "body";
      }
    },
    // 添加消息头
    add(tab) {
      if (tab.includes("header")) {
        this.reqForm.headers.push({
          value: "",
          key: ""
        });
      } else if (tab.includes("param")) {
        this.reqForm.params.push({
          value: "",
          key: ""
        });
      }
    },
    // 删除消息头
    removeDomain(item, tab) {
      if (tab.includes("header")) {
        let index = this.reqForm.headers.indexOf(item);
        if (index !== -1) {
          this.reqForm.headers.splice(index, 1);
        }
      } else if (tab.includes("param")) {
        let index = this.reqForm.params.indexOf(item);
        if (index !== -1) {
          this.reqForm.params.splice(index, 1);
        }
      }
    },
  }
};
</script>

<style lang="less" scoped>
.el-col {
  border-radius: 4px;
}
.el-button {
  margin-bottom: 20px;
}
.title {
  margin-bottom: 10px;
}
.edit {
  color: #fff;
  background-color: rgb(255, 0, 0);
  border-color: rgb(255, 0, 0);
}
.edit:hover,
.edit:focus {
  background: var(--el-button-hover-color);
  border-color: var(--el-button-hover-color);
  color: var(--el-button-font-color);
}
.edit1 {
  color: #fff;
  background-color: rgb(30, 130, 229);
  border-color: rgb(30, 130, 229);
}
.edit1:hover,
.edit1:focus {
  background: var(--el-button-hover-color);
  border-color: var(--el-button-hover-color);
  color: var(--el-button-font-color);
}
</style>

